﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Common.Lib.Assembly;
using NHibernate.Bytecode;
using NHibernate.Cfg;
using NHibernate.Connection;
using NHibernate.Dialect;
using NHibernate.Driver;

namespace NHibernate.Util
{
    public static class ConfigurationUtil
    {

        public static Configuration BuildMsSqlCeConfiguration(string connectionStr, IDictionary<string, string> properties, IDictionary<string, IEnumerable<string>> resources)
        {
            IDictionary<string, string> sqlCeProperties = new Dictionary<string, string>();
            sqlCeProperties.Add(NHibernate.Cfg.Environment.Dialect, typeof(MsSqlCeDialect).AssemblyQualifiedName);
            sqlCeProperties.Add(NHibernate.Cfg.Environment.ConnectionDriver, typeof(SqlServerCeDriver).AssemblyQualifiedName);
            sqlCeProperties.Add(NHibernate.Cfg.Environment.ConnectionString, connectionStr);
            sqlCeProperties.Add(NHibernate.Cfg.Environment.ConnectionProvider, typeof(DriverConnectionProvider).AssemblyQualifiedName);

            sqlCeProperties = CombineProperties(sqlCeProperties, properties);
            return BuildConfiguration(sqlCeProperties, resources);
        }

        public static Dictionary<string, string> GetDefaultProperties()
        {
            Dictionary<string, string> properties = new Dictionary<string, string>();
            properties.Add(NHibernate.Cfg.Environment.ShowSql, "true");
            properties.Add(NHibernate.Cfg.Environment.ReleaseConnections, "on_close");
            properties.Add(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, typeof(DefaultProxyFactoryFactory).AssemblyQualifiedName);
            return properties;
        }

        public static Configuration BuildConfiguration(IDictionary<string, string> properties, IDictionary<string, IEnumerable<string>> resources)
        {
            Configuration config = new Configuration();
            if (properties != null)
            {
                config.SetProperties(properties);
            }
            if (resources != null)
            {
                foreach (var assemblyName in resources.Keys)
                {
                    Assembly assembly = AssemblyUtil.LoadAssembly(assemblyName);
                    config.AddResources(resources[assemblyName], assembly);
                }
            }
            return config;
        }

        public static Dictionary<string, string> CombineProperties(IDictionary<string, string> properties, IDictionary<string, string> otherProperties)
        {
            Dictionary<string, string> result = new Dictionary<string, string>(properties);
            otherProperties.Keys.ToList().ForEach(propName =>
            {
                if (result.ContainsKey(propName))
                    result.Remove(propName);
                result.Add(propName, otherProperties[propName]);
            });
            return result;
        }
    }
}
